package userinterface;

import org.eclipse.swt.graphics.Color;

import java.awt.event.WindowEvent;
import java.io.File;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.forms.widgets.FormToolkit;

import logic.MainLogic;

public class UserInt {
	protected Shell shell;
	private final FormToolkit formToolkit= new FormToolkit(Display.getDefault());
	private Text barcodeBox;
	private Text sNumberBox;
	private List attending;
	private Composite composite;
	private ToolBar toolBar;
	private Label lblBarcode;
	private Label lblSnummer;
	private List arrived;
	private final Composite composite_1;
	private ToolItem tltmVerkoop;
	private ToolItem tltmParty;
	private MainLogic logic;
	private org.eclipse.swt.widgets.FileDialog fileChooser;
	private ToolItem tltmSetup;
	private final Composite compositeSetup;
	private boolean verkoopTab;

	/**
	 * Constructor van UserInt, wordt opgeroepen via mainlogic, initialiseren van de verschillende componenten in de windows.
	 * @param mainLogic
	 */
	public UserInt(MainLogic mainLogic){
		shell = new Shell();
		this.logic = mainLogic;
		composite = formToolkit.createComposite(shell, SWT.NONE);
		composite.setBounds(0, 96, 120, -96);
		composite_1 = new Composite(composite, SWT.NONE);
		compositeSetup = new Composite(shell, SWT.NONE);
		attending = new List(composite, SWT.BORDER);
		arrived = new List(composite_1, SWT.BORDER);
		toolBar = new ToolBar(shell, SWT.FLAT | SWT.RIGHT);
		tltmSetup = new ToolItem(toolBar, SWT.NONE);
		tltmVerkoop = new ToolItem(toolBar, SWT.NONE);
		tltmParty = new ToolItem(toolBar, SWT.NONE);
	}
	/**
	 * Filefilter is een functie die we nodig hebben voor het kiezen van welk bestand je nodig hebt, je kan zo instellen dat je enkel
	 * csv bestanden laat zien.  We gebruiken dit in de fileinitialiser.
	 * @param style = Je hebt zowel een save als load mode voor de filter(als het bestand reeds bestaat is het load, als het nog niet bestaat is het save mode)
	 */
	public void setupFileFilter(int style)
	{
		this.fileChooser = new org.eclipse.swt.widgets.FileDialog(shell,style);
		String[] filter= new String[] {"*.csv"};
		this.fileChooser.setFilterExtensions(filter);
	}
	/**
	 * Deze methode runt heel de tijd tijdens de duur van het programma, het zorgt voor het window.
	 */
	public void open() {
		Display display = Display.getDefault();
		createContents();
		shell.open();
		shell.layout();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	/**
	 * Create contents of the window.  Deze methode maakt het volledige window
	 * - er zijn 3 tabs met windows: verkoop(kaarten verkopen), party(op het feeesje zelf), setup(initialisatie files)
	 * Elke window heeft een standaard design, met listeners voor de aanpassingen
	 * De update knop dient voor connectie met database, lijsten heropfrissen.
	 */
	protected void createContents() {
		shell.setSize(767, 506);
		shell.setText("SWT Application");
		toolBar.setBounds(50, 10, 180, 31);
		formToolkit.adapt(toolBar);
		formToolkit.paintBordersFor(toolBar);
		
		tltmSetup.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				composite.setVisible(false);
				composite_1.setVisible(false);
				compositeSetup.setVisible(true);
			}
		});
		tltmSetup.setText("Setup");
		
		fileInitialiser();
		
		composite.setBounds(32, 80, 701, 407);
		formToolkit.paintBordersFor(composite);
		
		lblBarcode.setBounds(10, 10, 70, 17);
		formToolkit.adapt(lblBarcode, true, true);
		lblBarcode.setText("Barcode");
		
		barcodeBox = new Text(composite, SWT.BORDER);
		barcodeBox.setBounds(78, 10, 285, 27);
		formToolkit.adapt(barcodeBox, true, true);
		
		lblSnummer.setBounds(0, 66, 70, 17);
		formToolkit.adapt(lblSnummer, true, true);
		lblSnummer.setText("s-nummer");		ToolBar toolBar = new ToolBar(shell, SWT.FLAT | SWT.RIGHT);

		
		sNumberBox = new Text(composite, SWT.BORDER);
		sNumberBox.setBounds(78, 69, 285, 27);
		formToolkit.adapt(sNumberBox, true, true);
		
		Button btnBarcode = formToolkit.createButton(composite, "OK", SWT.NONE);
		btnBarcode.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				String barcode = barcodeBox.getText();
				if(barcode == null || barcode.length()!=12 )
					displayNegative();
				else{
					if(verkoopTab)
						logic.verkoopKaart(barcode);
					else{
						logic.attemptToEnter(barcode);
					}
				}
				barcodeBox.setText("");		
			}
		});
		btnBarcode.setBounds(407, 8, 91, 29);
		composite.setVisible(false);
		tltmParty.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				composite_1.setVisible(true);
				compositeSetup.setVisible(false);
				composite.setVisible(true);
				verkoopTab=false;
			}
		});
		tltmParty.setText("Party");
		
		tltmVerkoop.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				composite_1.setVisible(false);
				compositeSetup.setVisible(false);
				composite.setVisible(true);
				verkoopTab=true;
			}
		});
		tltmVerkoop.setText("Verkoop");
		
		Button btnSnumber = new Button(composite, SWT.NONE);
		btnSnumber.setBounds(407, 67, 91, 29);
		formToolkit.adapt(btnSnumber, true, true);
		btnSnumber.setText("OK");
		btnSnumber.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				String sNumber = sNumberBox.getText();
				if(sNumber == null || sNumber.length()!= 8 )
					displayNegative();
				else{
					if(verkoopTab)
						logic.verkoopKaartSn(sNumber);
					else{
						logic.attemptToEnterSn(sNumber);
					}
				}
			}
		});
		attending.setBounds(51, 165, 222, 232);
		formToolkit.adapt(attending, true, true);
		/**
		 * This method is used for removing an element from the attending list by double clicking the element.
		 */
		attending.addMouseListener(new MouseListener(){
			@Override
			public void mouseDoubleClick(MouseEvent arg0) {
				String sNumber = getSnumberFromItem(attending.getItem(attending.getSelectionIndex()));
				logic.removeFromAttended(sNumber);
				System.out.println(sNumber);
			}

			@Override
			public void mouseDown(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseUp(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
		});
		Label lblGenodigden = formToolkit.createLabel(composite, "Attending", SWT.NONE);
		lblGenodigden.setBounds(51, 142, 91, 17);
		
		composite_1.setBounds(393, 129, 275, 278);
		formToolkit.adapt(composite_1);
		formToolkit.paintBordersFor(composite_1);
		composite_1.setVisible(false);
		
		arrived.setBounds(30, 33, 212, 224);
		formToolkit.adapt(arrived, true, true);
		arrived.addMouseListener(new MouseListener(){
			@Override
			public void mouseDoubleClick(MouseEvent arg0) {
				String sNumber = getSnumberFromItem(arrived.getItem(arrived.getSelectionIndex()));
				logic.removeFromArrived(sNumber);
				System.out.println(sNumber);
			}

			@Override
			public void mouseDown(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseUp(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
		});
		Label lblGearriveerd = formToolkit.createLabel(composite_1, "Gearriveerd", SWT.NONE);
		lblGearriveerd.setBounds(10, 10, 112, 17);
		
		Button btnUpdate = new Button(shell, SWT.NONE);
		btnUpdate.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				logic.updateBarcodeTable();
				logic.updateLidTable();
				logic.updatePersoonTable();
			}
		});
		btnUpdate.setBounds(50, 45, 91, 29);
		formToolkit.adapt(btnUpdate, true, true);
		btnUpdate.setText("Update");
		
		

	}
	/**
	 * Het toevoegen van een persoon aan de lijst met verwachte mensen
	 * @param attendingMembers
	 */
	public void addToAttendList(String[] attendingMembers) {
		for (String s : attendingMembers) {
			this.attending.add(s);
		}
	}
	/**
	 * Het toevoegen van een persoon aan de lijst van personen die binnen zijn.
	 * @param arrivedMembers
	 */
	public void addToArrivedList(String[] arrivedMembers) {
		for (String s : arrivedMembers) {
			this.arrived.add(s);
		}
	}
	public void removeFromAttendList(String[] attendingMembers) {
		for (String s : attendingMembers)
			try {
				this.attending.remove(s);
			}
		catch (Exception localException) {
		}
	}
	
	public void removeFromArrivedList(String[] enteredMembers) {
		for (String s : enteredMembers)
			try {
				this.arrived.remove(s);
		}
		catch (Exception localException) {
		}
	}
	public void windowClosing(WindowEvent e)
	{
		this.shell.close();
	}
	public void CompletedSetup()
	{
		this.shell.setText("Setup Voltooid");
	}
	/**
	 * Deze methode toont je doorgegeven stukje tekst
	 * @param text die je wilt tonen
	 */
	public void displayText(String text) {
		this.shell.setText(text);
		Device device = Display.getCurrent();
		org.eclipse.swt.graphics.Color colorRed = new Color(device,255,0,0);
		shell.setBackground(colorRed);
		composite.setBackground(colorRed);
		composite_1.setBackground(colorRed);
	}
	/**
	 * Veel gebruikt als er iets mis is met wat je hebt ingegeven.
	 */
	public void displayNegative() {
		displayText("Not OK");
		Device device = Display.getCurrent();
		org.eclipse.swt.graphics.Color colorRed = new Color(device,255,0,0);
		shell.setBackground(colorRed);
		composite.setBackground(colorRed);
		composite_1.setBackground(colorRed);		
	}
	/**
	 * Als de actie voltooid is.
	 * 
	 */
	public void displayPositive() {
		displayText("OK");
		Device device = Display.getCurrent();
		org.eclipse.swt.graphics.Color color = new Color(device,0,255,0);
		this.shell.setBackground(color);
		this.composite.setBackground(color);
		this.composite_1.setBackground(color);
	}
	/**
	 * Deze methode regelt het compositeSetup menu, selecteren van de juiste csv file of gewoon een nieuwe aanmaken.
	 */
	private void fileInitialiser() {
		lblBarcode = new Label(composite, SWT.NONE);
		lblSnummer = new Label(composite, SWT.NONE);
		compositeSetup.setBounds(64, 95, 654, 338);
		formToolkit.adapt(compositeSetup);
		formToolkit.paintBordersFor(compositeSetup);
		
		Label lblIsErAl = new Label(compositeSetup, SWT.NONE);
		lblIsErAl.setBounds(65, 27, 547, 24);
		formToolkit.adapt(lblIsErAl, true, true);
		lblIsErAl.setText("Is er al een file met gegevens over het evenement op deze computer?");
		
		Button btnJa = new Button(compositeSetup, SWT.NONE);
		btnJa.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				setupFileFilter(SWT.OPEN);
				String path = UserInt.this.fileChooser.open();
				if (path == null) 
					fileInitialiser();
				else{
					File file = new File(path);
					UserInt.this.logic.loadPartyTable(file);
				}
			}
		});
		btnJa.setBounds(111, 161, 91, 29);
		formToolkit.adapt(btnJa, true, true);
		btnJa.setText("JA");
		
		Button btnNee = new Button(compositeSetup, SWT.NONE);
		btnNee.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				setupFileFilter(SWT.SAVE);
				String path = UserInt.this.fileChooser.open();
				if (path == null) 
					fileInitialiser();
				else {
					File file = new File(path);
					UserInt.this.logic.setPartySaveLocation(file);
				}
			}
		});
		btnNee.setBounds(414, 161, 91, 29);
		formToolkit.adapt(btnNee, true, true);
		btnNee.setText("NEE");		
	}
	public String getSnumberFromItem(String item){
		String [] items = item.split("-");
		String sNumber = items[0].trim();
		return sNumber;
	}
}
